#ifndef 	__ENGINE_INIFILE_HPP_INCLUDED__
#define		__ENGINE_INIFILE_HPP_INCLUDED__

#include	"Strings.h"
#include	<map>

/**
 * Helper class for parsing INI configuration file.
 *
 * NOTICE:
 *
 *	1. All keys must belong to one session. There's NO default global session.
 *	2. Key and session can use '"' to contain special characters.
 *	3. Both '#' and ';' can used for comments.
 */
class IniFile {
public:
	typedef std::map<std::string, std::map<std::string, std::string>>	Sessions;

public:
	IniFile() {}

	/**
	 * Load an INI file in gaven path.
	 *
	 * \param	path	Path to find this file.
	 * \return	Is this file successfully loaded. You can use GetError() to get the detail error.
	 **/
	bool Load(const std::string & path);

	/**
	 * If this INI file failed to load, this will return the detail information.
	 *
	 * \return	Detail information for failure.
	 **/
	std::string	GetError();

	/**
	 * Get all sessions' name in this INI file.
	 *
	 * \return	All sessions' name in a vector.
	 **/
	std::vector<std::string> GetSessions();

	/**
	 * Get all keys in a session.
	 * 
	 * \param	session		Name of session
	 * \return	All keys belong to this session.
	 **/
	std::vector<std::string> GetKeys(const std::string & session);

	/**
	 * Get value of special configuration.
	 *
	 * \param	session	Session name of this configuration.
	 * \param	key		Key of this configuration.
	 * \param	def		Default value for this configuration.
	 * \return	Value of this configuration. If the configuration does NOT exists, returns the default value.
	 **/
	template<typename T>
	T Get(const std::string & session, const std::string & key, const T & def) const {
		auto s = _sessions.find(session);
		if (s == _sessions.end()) return def;

		auto k = s->second.find(key);
		if (k == s->second.end()) return def;

		return Parse<T>(k->second);
	}

private:
	Sessions	_sessions;
	int			_error;
};

#endif//!	__ENGINE_INIFILE_HPP_INCLUDED__